﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Web;
using System.Xml.Linq;
using VH.SharePoint.Api.MetaWeblog;

namespace VH.SharePoint.Api.WLW
{
    public class WlwHandler :IHttpHandler
    {
        public bool IsReusable
        {
            get { return false; }
        }

        private HttpContext currentContext;

        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.HttpMethod != "POST")
                throw new NotSupportedException();
            currentContext = context;
            if (context.Request.RawUrl.EndsWith("lists.asmx"))
            {
                ProcessListsAsmx(GetContents(context.Request));
            }
        }

        private string GetContents(HttpRequest request)
        {
            string contents;
            using (Stream receiveStream = request.InputStream)
            {
                using (var readStream = new StreamReader(receiveStream, Encoding.UTF8))
                {
                    contents = readStream.ReadToEnd();
                }
            }
            return contents;
        }

        private void ProcessListsAsmx(string xml)
        {
            var root = XElement.Parse(xml);
            var deleteAttachement = root.Descendants(XName.Get("DeleteAttachment", "http://schemas.microsoft.com/sharepoint/soap/"));
            if (deleteAttachement.Any())
            {
                ProcessDeleteAttachment(deleteAttachement.FirstOrDefault());
            }
            var addAttachment  = root.Descendants(XName.Get("AddAttachment", "http://schemas.microsoft.com/sharepoint/soap/"));
            if (addAttachment.Any())
            {
                ProcessAddAttachment(addAttachment.FirstOrDefault());
            }
        }

        private void ProcessAddAttachment(XElement xElement)
        {
            var fileName = xElement.Element(XName.Get("fileName", "http://schemas.microsoft.com/sharepoint/soap/")).Value;
            byte[] contents = Convert.FromBase64String(xElement.Element(XName.Get("attachment", "http://schemas.microsoft.com/sharepoint/soap/")).Value);

            var mediaInfo = new MediaObjectInfo {FileName = fileName};
            Storage.BlogRepository.Medias.Create(mediaInfo, contents);

            var responsestr = string.Format("<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><AddAttachmentResponse xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\"><AddAttachmentResult>{0}</AddAttachmentResult></AddAttachmentResponse></soap:Body></soap:Envelope>",
                                            mediaInfo.Url);

            ResponseXml(responsestr);

        }

        private void ProcessDeleteAttachment(XElement xElement)
        {
            try
            {
                var url = xElement.Element(XName.Get("url", "http://schemas.microsoft.com/sharepoint/soap/")).Value;
                var index = url.LastIndexOf('/');
                if (index != -1)
                {
                    url = url.Substring(index + 1);
                }
                var medias = Storage.BlogRepository.Medias;
                medias.Delete(new MediaObjectInfo{FileName = url});
                var responsestr =
                    "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" />";
                                    

                ResponseXml(responsestr);
            }
            catch (Exception ex)
            {
                var returnError = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown.</faultstring><detail><errorstring xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">Specified argument was out of the range of valid values. Parameter name: leafName</errorstring></detail></soap:Fault></soap:Body></soap:Envelope>";
                ResponseError(returnError);
            }
        }

        private void ResponseXml(string content)
        {
            currentContext.Response.StatusCode = 200;
            currentContext.Response.ContentType = "text/xml";
            currentContext.Response.Write(content);
        }

        private void ResponseError(string content)
        {
            currentContext.Response.StatusCode = 500;
            currentContext.Response.ContentType = "text/xml";
            currentContext.Response.Write(content);
        }

    }
}
